package main

import (
	"fmt"
	"net"
	"strings"
)

//用户类
type User struct {
	Name    string
	Adder   string
	Channel chan string
	con     net.Conn
	//v4 封装业务逻辑
	server *Server
}

//创建每个用户类
func NewUser(conn net.Conn, server *Server) *User {
	userAdder := conn.RemoteAddr().String()
	user := &User{
		Name:    userAdder,
		Adder:   userAdder,
		Channel: make(chan string),
		con:     conn,
		server:  server,
	}
	//启动监听当前user channel消息的goroutine
	go user.ListenMessage()
	return user
}

//每个用户需要自己去监听channel是否有数据，有就直接发送给对端客户端
func (this *User) ListenMessage() {
	for {
		//获取当前的 channel 是否有消息，会阻塞，消息是从 服务器的 MessageChannel 填送的
		msg := <-this.Channel
		if len(msg) > 0 {
			//向连接中写数据
			this.con.Write([]byte(msg + "\n"))
			fmt.Println("向客户端发送数据 " + this.Adder + "   " + msg)
		}
	}
}

//用户的上线业务
func (this *User) Online() {
	//用户上线,将用户加入到onlineMap中
	this.server.mapLock.Lock()
	this.server.OnlineMap[this.Name] = this
	this.server.mapLock.Unlock()
	//广播当前用户上线消息
	this.server.BroadCast(this, "已上线\n")
}

//用户的下线业务
func (this *User) Offline() {
	//用户下线,将用户从onlineMap中删除
	this.server.mapLock.Lock()
	delete(this.server.OnlineMap, this.Name)
	this.server.mapLock.Unlock()
	//广播当前用户上线消息
	this.server.BroadCast(this, "下线\n")
}

//用户处理广播消息的业务
func (this *User) DoMessage(msg string) {
	//查询当前在线用户都有哪些
	if msg == "who" {
		this.server.mapLock.Lock()
		for _, user := range this.server.OnlineMap {
			onlineMsg := "[" + user.Adder + "]" + user.Name + ":" + "在线..."
			this.SendMsg(onlineMsg)
		}
		this.server.mapLock.Unlock()
	} else if len(msg) > 7 && msg[:7] == "rename|" {
		//消息格式:rename|张三
		name := strings.Split(msg, "|")[1]
		_, ok := this.server.OnlineMap[name]
		if ok {
			this.SendMsg("用户名已经存在")
		} else {
			this.server.mapLock.Lock()
			delete(this.server.OnlineMap, this.Name)
			this.server.OnlineMap[name] = this
			this.server.mapLock.Unlock()

			this.Name = name
			this.SendMsg("更新用户名成功: " + name)
		}
	} else if len(msg) > 4 && msg[:3] == "to|" {
		//消息格式:to|张三|消息内容
		//1 获取对方的用户名
		remoteName := strings.Split(msg, "|")[1]
		if remoteName == "" {
			this.SendMsg("消息格式不正确，请使用 \"to|张三|你好啊\"格式。")
			return
		}
		//2 根据用户名 得到对方User对象
		remoteUser, ok := this.server.OnlineMap[remoteName]
		if !ok {
			this.SendMsg("该用户名不不存在")
			return
		}

		content := strings.Split(msg, "|")[2]
		if content == "" {
			this.SendMsg("无消息内容，请重发")
			return
		}
		remoteUser.SendMsg(this.Name + " 对您说: " + content)
	} else {
		//广播消息
		this.server.BroadCast(this, msg)
	}

}

//给当前User对应的客户端发送消息
func (this *User) SendMsg(msg string) {
	fmt.Println(msg + "\n")
	this.con.Write([]byte(msg + "\n"))
}
